home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-09-07 | 49.0 KB | 1,565 lines |
-
- Another great doc for the budding assembly langage programmers.
- Part 6-10 of of the 68000 Machine Language Course
- Brought to you by Sewer Software
-
-
-
- ASSEMBLY LANGUAGE COURSE PART VI by Mark van den Boer
-
- Shift and Rotate Operations
-
- Instruction: ASL
- Syntax: ASL #,Dn (the immediate operand always modulo 8)
- ASL Dn,Dn (the first operand always modulo 8)
- ASL <ea>
- Data sizes: byte, word, long except for ASL <ea> which only
- allows word and long as data sizes.
- Condition codes affected:
- X set to the last bit shifted out
- N set to the most significant bit of the result
- Z set if the result is zero, cleared otherwise
- V set if the most significant bit is changed
- during the operation
- C see the X-bit
-
-
-
-
-
- Addressing modes allowed with the ASL <ea> instruction:
- Destination:
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- Function: Perform a shift left of the destination operand. This
- instruction can be used as a fast form of multiplying an
- operand with a power of two. On a processor like the
- 6502 this instruction is the only way to perform a
- multiply operation. The lower bit of the destination is
- always set to zero.
- Examples:
- Instruction Before After
- ASL.L d0,d1 d0=33333333 d0=33333333
- d1=00000005 d1=00000028
- ASL.W $4ee $4ee=0009 $4ee=0012
-
-
- Instruction: ASR
- Syntax: ASR #,Dn (the immediate operand always modulo 8)
- ASR Dn,Dn (the first operand always modulo 8)
- ASR <ea>
- Data sizes: byte, word, long except for ASR <ea> which only
- allows word and long as data sizes.
- Condition codes affected:
- X set to the last bit shifted out
- N set to the most significant bit of the result
- Z set if the result is zero, cleared otherwise
- V set if the most significant bit is changed
- during the operation
- C see the X-bit
- Addressing modes allowed with the ASR <ea> instruction:
- Destination:
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- Function: Perform a shift right of the destination operand. This
- instruction can be used as a fast form of dividing an
- operand with a power of two. On a processor like the
- 6502 this instruction is the only way to perform a
- divide operation. The upper bit (sign bit) is always
- repeated.
- Examples:
- Instruction Before After
- ASR.L d0,d1 d0=33333333 d0=33333333
- d1=00000005 d1=00000002
- ASR.W $4ee $4ee=8009 $4ee=c004
-
-
- Instruction: LSL
- See the ASL instruction. The LSL instruction is exactly the same.
- At the moment I haven't got the machine codes for the ASL and LSL
- operations but I think that even the machine codes are the same.
- E.g. on the 6809 both ASL and LSL exist but translate to the same
- machine code.
-
-
-
- Instruction: LSR
- Syntax: LSR #,Dn (the immediate operand always modulo 8)
- LSR Dn,Dn (the first operand always modulo 8)
- LSR <ea>
- Data sizes: byte, word, long except for LSR <ea> which only
- allows word and long as data sizes.
- Condition codes affected:
- X set to the last bit shifted out
- N set to the most significant bit of the result
- Z set if the result is zero, cleared otherwise
- V set if the most significant bit is changed
- during the operation
- C see the X-bit
- Addressing modes allowed with the LSR <ea> instruction:
- Destination:
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- Function: Perform a shift right of the destination operand. This
- instruction differs from ASR in that the high order bit
- is always cleared.
- Examples:
- Instruction Before After
- LSR.L d0,d1 d0=33333333 d0=33333333
- d1=00000005 d1=00000002
- LSR.W $4ee $4ee=0009 $4ee=0004
-
-
- Instruction: ROL
- Syntax: ROL #,Dn (the immediate operand always modulo 8)
- ROL Dn,Dn (the first operand always modulo 8)
- ROL <ea>
- Data sizes: byte, word, long
- Condition codes affected:
- X not affected
- N set to the most significant bit of the result
- Z set if the result is zero, cleared otherwise
- V always cleared
- C set to the last bit shifted out the operand
-
- Addressing modes allowed with the ROL <ea> instruction:
- Destination:
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- Function: Perform a bitwise rotate left of the destination
- operand.
- Examples:
- Instruction Before After
- ROL.L d0,d1 d0=00000001 d0=00000001
- d1=88000001 d1=10000002 (C bit set)
- ROL.W $4ee $4ee=8009 $4ee=0012
-
-
-
-
-
-
- Instruction: ROR
- Syntax: ROR #,Dn (the immediate operand always modulo 8)
- ROR Dn,Dn (the first operand always modulo 8)
- ROR <ea>
- Data sizes: byte, word, long
- Condition codes affected:
- X not affected
- N set to the most significant bit of the result
- Z set if the result is zero, cleared otherwise
- V always cleared
- C set to the last bit shifted out the operand
- Addressing modes allowed with the ROR <ea> instruction:
- Destination:
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- Function: Perform a bitwise rotate right of the destination
- operand.
- Examples:
- Instruction Before After
- ROR.L d0,d1 d0=00000001 d0=00000001
- d1=88000001 d1=c4000000 (C bit set)
- ROR.W $4ee $4ee=8009 $4ee=c004
-
-
- Instruction: ROXL
- Syntax: ROXL #,Dn (the immediate operand always modulo 8)
- ROXL Dn,Dn (the first operand always modulo 8)
- ROXL <ea>
- Data sizes: byte, word, long
- Condition codes affected:
- X set to the last bit shifted out the operand
- N set to the most significant bit of the result
- Z set if the result is zero, cleared otherwise
- V always cleared
- C set to the last bit shifted out the operand
-
-
-
-
- Addressing modes allowed with the ROXL <ea> instruction:
- Destination:
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- Function: Perform a bitwise rotate left of the destination
- operand. There is very little difference with the ROL
- instruction. By the way, it is very handy to have a
- wordprocessor with cut/paste and find/replace
- facilities. All I did was cut out the complete ROL
- instruction and replaced all ROL's by ROXL's.
- Examples:
- Instruction Before After
- ROXL.L d0,d1 d0=00000001 d0=00000001
- d1=88000001 d1=10000002
- ROXL.W $4ee $4ee=8009 $4ee=0012
-
-
- Instruction: ROXR
- Syntax: ROXR #,Dn (the immediate operand always modulo 8)
- ROXR Dn,Dn (the first operand always modulo 8)
- ROXR <ea>
- Data sizes: byte, word, long
- Condition codes affected:
- X set to the last bit shifted out the operand
- N set to the most significant bit of the result
- Z set if the result is zero, cleared otherwise
- V always cleared
- C set to the last bit shifted out the operand
- Addressing modes allowed with the ROXR <ea> instruction:
- Destination:
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
-
-
- Function: Perform a bitwise rotate right of the destination
- operand. There is very little difference with the ROR
- instruction. By the way, it is very handy to have a
- wordprocessor with cut/paste and find/replace
- facilities. All I did was cut out the complete ROXL
- instruction and replaced all ROXL's by ROXR's.
- Examples:
- Instruction Before After
- ROXR.L d0,d1 d0=00000001 d0=00000001
- d1=88000001 d1=10000002
- ROXR.W $4ee $4ee=8009 $4ee=0012
-
-
-
- MC 68000 MACHINE LANGUAGE COURSE PART VII by Mark van den Boer
-
- I would like to dedicate this part to Willeke, who gives Richard
- sleepless nights and the inspiration to write even more exciting
- issues of ST NEWS. I only saw Willeke on photograph, but she must
- be a fine girl. In my opinion there are three qualities which a
- girl must have, to qualify as a fine girl. These are: 1) like
- Queensrche, 2) like ST NEWS (no, she doesn't have to like this
- particular machine language course).
- Now, you're all anxious to know the third quality, aren't you? If
- you think you know the third one, send your answer to ST NEWS. A
- bottle of wine will be raffled among the persons who gave the
- right answer. There will be another bottle for the most original
- answer!
-
- Bit Manipulation instructions
-
- Instruction: BTST
- Syntax: BTST Dn,<ea> or BTST #,<ea>
- Data sizes: only byte when <ea> is an address. Only long when
- <ea> is a data register.
-
- Condition codes affected:
- X not affected
- N not affected
- Z set if the result is zero, cleared otherwise
- V not affected
- C not affected
- Addressing modes allowed:
- Destination:
- Dn
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- w(PC)
- b(PC,Rn)
- # (only when source is Dn)
-
-
-
- Function: Test a single bit of an effective address operand. Bits
- are numbered from 0 to 31, where 0 is the least
- significant bit (you could use this instruction to test
- if a number is odd). This instruction is useful when
- specific bits of an operand have to be checked. E.g.
- when reading joystick information one could test with a
- single instruction whether the fire-button was pressed
- or not. Compared to the 6502 and 6809 this instruction
- (in fact all bit manipulation instructions) are a step
- forward, since with these older processors one had to
- put the data in a register first, then filter the bit
- with an AND-operation and then the Z-bit in the status
- register was at last set. Viva el 68000!! Since this
- instruction has the rather odd property of only working
- on byte and long operands it is important that you
- remember what I wrote in a previous part about
- specifying data sizes.
-
-
-
-
-
- Examples:
- Instruction Before After
- BTST.B #5,$345678 $345678 $345678 contains
- contains $78 $78
- Z-bit is 1
- BTST.L d0,d1 d0=0 d0=0
- d1=$12345678 d1=$12345678
- Z-bit is 0
-
-
- Instruction: BCLR
- Syntax: BTST Dn,<ea> or BTST #,<ea>
- Data sizes: only byte when <ea> is an address. Only long when
- <ea> is a data register.
- Condition codes affected:
- X not affected
- N not affected
- Z set if the result is zero, cleared otherwise
- V not affected
- C not affected
-
-
- Addressing modes allowed:
- Destination:
- Dn
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- w(PC)
- b(PC,Rn)
- # (only when source is Dn)
- Function: Bit test and CLeaR. First tests the bit to be cleared
- and sets the Z-bit accordingly, then clears the
- specified bit.
-
-
-
-
-
-
- Examples:
- Instruction Before After
- BCLR.B #5,$345678 $345678 $345678 contains
- contains $78 $58
- Z-bit is 1
- BCLR.L d0,d1 d0=0 d0=0
- d1=$12345678 d1=$12345678
- Z-bit is 0
-
-
- Instruction: BSET
- Syntax: BSET Dn,<ea> or BSET #,<ea>
- Data sizes: only byte when <ea> is an address. Only long when
- <ea> is a data register.
- Condition codes affected:
- X not affected
- N not affected
- Z set if the result is zero, cleared otherwise
- V not affected
- C not affected
-
-
- Addressing modes allowed:
- Destination:
- Dn
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- w(PC)
- b(PC,Rn)
- # (only when source is Dn)
- Function: Bit test and SET. First tests the bit to be set and sets
- the Z-bit accordingly, then sets the specified bit. This
- instruction and the BCLR instruction can be used as
- alternatives to the TAS-instruction.
-
-
-
-
-
- Examples:
- Instruction Before After
- BSET.B #5,$345678 $345678 $345678 contains
- contains $78 $78
- Z-bit is 1
- BSET.L d0,d1 d0=0 d0=0
- d1=$12345678 d1=$12345679
- Z-bit is 0
-
-
- Instruction: BCHG
- Syntax: BCHG Dn,<ea> or BCHG #,<ea>
- Data sizes: only byte when <ea> is an address. Only long when
- <ea> is a data register.
- Condition codes affected:
- X not affected
- N not affected
- Z set if the result is zero, cleared otherwise
- V not affected
- C not affected
-
-
- Addressing modes allowed:
- Destination:
- Dn
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- w(PC)
- b(PC,Rn)
- # (only when source is Dn)
- Function: Bit test and CHanGe. First tests the bit to be changed
- and sets the Z-bit accordingly, then changes the
- specified bit.
-
-
-
-
-
-
- Examples:
- Instruction Before After
- BCHG.B #5,$345678 $345678 $345678 contains
- contains $78 $58
- Z-bit is 1
- BCHG.L d0,d1 d0=0 d0=0
- d1=$12345678 d1=$12345679
- Z-bit is 0
-
-
- Binary Coded Decimal (BCD) instructions
-
- To understand this instructionclass we must first know what a BCD-
- digit is. It is a representation of decimal digits in an array of
- bytes (array may be of length 1 or greater). In every byte the
- decimal number 0 to 99 can be represented. This is done as
- follows: a byte can be divided into two four-bit parts, called
- nibbles. In every nibble, one decimal digit is represented. This
- implicates that the binary combination 1010 can never occur in BCD
- representation, since it isn't in the decimal range from 0 to 9.
-
-
- The BCD-representation is especially convenient when printing such
- a digit, since it doesn't take much calculation to convert it to a
- printable character. A disadvantage of the BCD-representation is
- that one doesn't use the full storage capacity of a byte or word.
- The 68000 has three special BCD-artithmetic instructions.
-
-
- Instruction: ABCD
- Syntax: ABCD Dn,Dn or ABCD -(An),-(An)
- Data sizes: byte
- Condition codes affected:
- X set by carry out of most significant
- BCD-nibble, cleared otherwise
- N undefined
- Z set if the result is zero, cleared otherwise
- V undefined
- C same as X-bit
- Function: Add two BCD-digits. The predecremeting addressing mode
- has been provided for computations with multiple
- precision BCD-numbers. This implies that the most
- significant BCD-numbers must be stored in the lower
- memory addresses.
- Examples:
- Instruction Before After
- ABCD.B d0,d1 d0=$53 d0=$53
- d1=$32 d1=$85
-
-
- Instruction: SBCD
- Syntax: SBCD Dn,Dn or SBCD -(An),-(An)
- Data sizes: byte
- Condition codes affected:
- X set by carry out of most significant
- BCD-nibble, cleared otherwise
- N undefined
- Z set if the result is zero, cleared otherwise
- V undefined
- C same as X-bit
- Function: Subtract two BCD-digits.
- Examples:
- Instruction Before After
- ABCD.B d0,d1 d0=$53 d0=$53
- d1=$32 d1=$21
-
- Instruction: NBCD
- Syntax: NBCD <ea>
- Data sizes: byte
- Addressing modes allowed:
- Dn
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- Condition codes affected:
- X set by borrow out of most significant
- BCD-nibble, cleared otherwise
- N undefined
- Z set if the result is zero, cleared otherwise
- V undefined
- C same as X-bit
-
-
-
- Function: Negate a BCD-number. How it functions can be best
- described with an example. Let's negate $23. The NBCD
- operation yields $77. Now, how did we get this result?
- It's easy, just subtract $23 from $99 and you've got it.
- Examples:
- Instruction Before After
- NBCD.B d0 d0=$43 d0=$56
-
-
- This is the end of part seven. Next time I will deal with all
- program flow instruction, such as branches and jumps.
-
-
-
- MC 68000 ASSEMBLY LANGUAGE COURSE PART VIII by Mark van den Boer
-
- Program Control Instructions
-
- This class of instructions enables a programmer to create loops
- and IF-THEN-ELSE like decisions. That's why it's the most
- important group of instructions and every programmer should have
- a thorough knowledge of this group. This class of instructions
- are specifically meant to affect the program counter.
-
- Instructions: Bcc (cc stands for Condition Code)
- Syntax: Bcc <address>
- Data sizes: Byte or word. This implicates that the branch-
- instructions can branch in an area of 32K. When
- using a branch with a byte offset you can put a .S
- suffix behind the instruction e.g. BEQ.S . When
- using a branch with a word offset you can put a .W
- suffix behind the instruction e.g. BEQ.W . Most
- assemblers will determine if the short or word
- form is needed. Also most assemblers will optimize
- word-branches to byte-branches whenever possible.
-
- Condition codes affected:
- None
- Function: Test a combination of the NZVC-flags in the status-
- register and conditionally perform a branch to another
- address. If the testing of the condition codes is true,
- then the branch will be taken, in the other the
- instruction immediately following the Bcc instruction
- will be executed. A total of 15 possible variations of
- this instruction are listed below.
- BCC: where CC stands for Carry Clear. The branch is
- taken if the C-bit is 0. This instruction is often
- used in combination with shift and rotate
- instructions.
- BCS: where CS stands for Carry Set. The branch is taken
- if the C-bit is 1. This instruction is the
- counterpart of the BCC-instruction.
- BEQ: where EQ stand for EQual. The branch is taken if
- the Z-bit is 1. This instruction is often used
- after a TST-instruction or CMP-instruction.
- BNE: where NE stands for Not Equal. The branch is taken
- if the Z-bit is 0. This instruction is the
- counterpart of the BNE-instruction.
- BPL: where PL stands for PLus. The branch is taken if
- the N-bit is 0. This instruction is often used
- after a TST-instruction or CMP-instruction.
- BMI: where MI stands for MInus. The branch is taken if
- the N-bit is 1. This instruction is the
- counterpart of the BPL-instruction.
- BVC: where VC stands for oVerflow Clear. The branch is
- taken if the V-bit is 0. This instruction is often
- used after an Integer Arithmetic instruction like
- ADD, SUB, MUL etc.
- BVS: where VS stands for oVerflow Set. The branch is
- taken if the V-bit is 1. This instruction is the
- counterpart of the BVC-instruction.
- BRA: where RA stands for bRanch Always. This
- instruction is often used at the end of a loop to
- go back to the beginning of the loop.
- Branches often used after an arithmetic operation on
- two's complement numbers.
- BGE: where GE stands for Greater or Equal. This branch
- is taken if the N and V-bits contain the same
- value.
-
- BGT: where GT stands for Greater Than. This branch is
- taken in the following cases:
- - N is 1, V is 1, Z is 0
- - N is V is Z is 0
- BLE: where LE stands for Lower or Equal. This branch is
- taken in the following cases:
- - Z is 1
- - N and V-bits contain different values
- BLT: where LT stands for Less Than. This branch is
- taken if the N and V-bits contain different
- values.
- Brances often used after an arithmetic operation on
- unsigned numbers.
- BHI: where HI stands for HIgher. This branch is taken
- if the N and V-bits contain the same value.
- BLS: where LS stands for Lower or Same. This branch is
- taken if the C and Z-bits contain different
- values.
- Example:
- This shows a piece of a C-program and an equivalent
- piece of a PASCAL-program which are translated into
- assembler. (variabele is signed)
- C:
- if (variable == 1 || variable > 4) variable = 5;
- else var *= 3;
- PASCAL:
- if (variable == 1) or (variable > 4)
- then variable := 5
- else variable := variable * 3
-
- * Most assemblers will optimize the branch-instructions
- * to the short forms
- CMP.W #1,variable
- BEQ L10000
- CMP.W #4,variable
- BLE L2
- L10000:
- MOVE.W #5,variable
- BRA L3
- L2:
- MOVE.W variable,R0
- MULS #3,R0
- MOVE.W R0,variable
- L3:
- Instructions: DBcc (cc stands for Condition Code)
- Syntax: DBcc Dn,<address>
- Data sizes: byte or word. This implicates that the branch-
- instructions can branch in an area of 32K. Dn is
- considered to contain a word.
- Condition codes affected:
- None
- Function:
- The group of Decrement and Branch (DBcc) instructions
- provide an efficient way of creating loops. They are
- nearly always placed at the end of a loop. First the
- condition is tested, then the dataregister is
- decremented. The branch is taken in the following
- cases:
- - Dn is -1;
- - The condition cc in DBcc is satisfied.
- There are 16 possible variations of this instruction.
- They all are nearly the same as the Bcc-instructions,
- with two exceptions. These are:
- DBF or DBRA:
- This loop can only be terminated by count since
- the other condition can never be satisfied.
- DBT: Only performs a decrement on the dataregister and
- never branches. To me this seems a pretty useless
- instruction, which is only there to make the DBcc
- series logically complete.
- Example:
- This piece of code is an efficient implementation of
- the strcpy-function of the C-language. A0 contains the
- address of the source string and A1 contains the
- address of the destination string. In C the end of a
- string is marked by a byte containing 0.
- MOVE.W #$ffff,D0
- LOOP: MOVE.B (A0)+,(A1)+
- DBEQ D0,LOOP
- This piece of code can easily be transformed into the
- strncpy-function by loading D0 with the appropriate
- value.
-
-
- Instructions: Scc (cc stands for Condition Code)
- Syntax: Scc <address>
- Data sizes: byte.
-
- Condition codes affected:
- None
- Function: Sets a byte to $ff if the condition codes satisfie. If
- the condition is not satisfied the byte is set to 0.
- This group of 16 instructions is rarely used. Nearly
- all forms are the same as the DBcc group except for the
- following two instructions:
- SF: the same as a CLR.B instruction
- ST: the same as a MOVE.B #$ff, <address>
- Example:
- Be inventive, invent one yourself!
-
-
- Instruction: BSR, JSR
- Syntax: BSR <address>
- JSR <address>
- Data sizes: none
- Condition codes affected:
- none
-
-
-
- Addressing modes allowed (only for JSR):
- Destination:
- (An)
- w(An)
- b(An,Rn)
- w
- l
- w(PC)
- b(PC,Rn)
- Function: The BSR (Branch to SubRoutine) and JSR (Jump to
- SubRoutine) instructions are used for calling
- subroutines. BSR can branch in a range of 32K. JSR
- should be used when a jump out of the 32K range is
- needed. Some assemblers optimize JSR into BSR
- instructions whenever possible, since BSR is more
- efficient than JSR. When executing a BSR/JSR
- instruction, the 68000 first pushes the PC (program-
- counter) on the stack and then load the PC with the new
- address. See below for the RTS (ReTurn from Subroutine)
- instruction.
-
-
- Instruction: RTS
- Syntax: RTS
- Data sizes: none
- Condition codes affected:
- none
- Function: Counterpart of BSR/JSR instructions. Reloads the PC
- with the value on top of the stack. This value will
- nearly always have been put on top of the stack by a
- BSR/JSR instruction.
- Example: * the strcpy function discussed before
- STRCPY:
- MOVE.W #$FFFF,D0
- LOOP: MOVE.W (A0)+,(A1)+
- DBEQ D0, LOOP
- RTS
- * some other code
- BEGIN:
- MOVE.L #SOURCE,A0
- MOVE.L #DEST,A1
- JSR STRCPY
- RTS
-
- * the strings are put in a data area
- .DATA
- * 80 bytes for every string
- SOURCE .DS.B 80
- DEST .DS.B 80
- * .DS.B means Define Storage Byte
- * so 80 bytes are define as storage for each string
-
-
- Instruction: JMP
- Syntax: JMP <ea>
- Data sizes: none
- Condition codes affected:
- none
-
-
-
-
-
-
-
-
- Addressing modes allowed:
- Destination:
- (An)
- w(An)
- b(An,Rn)
- w
- l
- w(PC)
- b(PC,Rn)
- Function: Transfer program control to another address. The PC is
- loaded with the specified address. In fact this is a
- variant of the MOVE instruction. In this case the
- destination register is inherently defined, namely the
- PC-register. Therefore we could translate JMP <ea> to
- MOVE.L <ea>,PC .
-
- Instruction: RTR
- Syntax: RTR
- Data sizes: none
- Condition codes affected:
- none
-
- Function: ReTurn and Restore. Counterpart of BSR/JSR
- instructions. Reloads the PC with the value on top of
- the stack. This value will nearly always have been put
- on top of the stack by a BSR/JSR instruction. The only
- difference with the RTS is that with this instruction
- also the CCR is reloaded. This instruction is rarely
- used but comes in handy when one doesn't want a
- subroutine to influence the condition codes. Before the
- JSR instruction you should use the instruction:
- MOVE.B CCR,-(A7)
- which pushes the CCR on the stack
-
- Next time: The last part of the instruction set. These are the
- instructions which can only be executed when supervisor-mode is
- active.
-
-
-
- ASSEMBLY LANGUAGE COURS PART IX by Mark van den Boer
-
- System Control instructions
-
- In this part of the course the last group of instructions will be
- explained. This group of instructions deals with the supervisor-
- mode and are therefore sometimes referred to as system control
- instructions. To remind you: the S-bit in the SR (status
- register) of the 68000 determines whether the 68000 is in
- supervisor-mode or not. Many of these instructions deal with so
- called exceptions. Exception is another word for interrupt and
- these are used to force program control immediately to a specific
- routint exception handler routine. Exceptions are used to detect
- situations that are urgent and need to be handled directly.
- Therefore every exception has a vector assigned to it. This
- vector is a pointer to a routine which performs some action which
- should be taken when such an exception occurs. The exception
- vectors are located in the first 256 longwords of memory.
-
-
-
-
- Instruction: CHK
- Syntax: CHK <ea>,Dn
- Data sizes: word
- Condition codes affected:
- X not affected
- N Set if Dn is less than zero, cleared if <ea>
- less than Dn, in all other cases undefined
- Z
- V
- C always undefined
-
-
-
-
-
-
-
-
-
-
-
-
- Addressing modes allowed:
- Source:
- Dn
- (An)
- (An)+
- -(An)
- w(An)
- b(An,Rn)
- w
- l
- w(PC)
- b(PC,Rn)
- #
- Destination:
- Dn
-
-
-
-
-
-
-
- Function: Compares the contents of the effective address operand
- with the data-register. If the data register is less
- than zero (the data register is always considered to be
- a signed word) or greater than the contents of <ea>,
- then an exception occurs. The pointer to this
- exception-routine is located at address $18. This
- instruction is used to check if a data register is
- within a range. It is often used by high-level
- languages such as PASCAL to perform array-bound
- checking.
- Examples:
- Instruction Before After
- CHK #50,D0 D0=45 D0=45
- No exception occured, if D0 had been 51
- or greater then an exception would have
- occured.
-
-
- Instruction: MOVE USP (privileged instruction)
- Syntax: MOVE USP,An or MOVE An,USP
- Data sizes: long
-
- Condition codes affected:
- X
- N
- Z
- V
- C not affected
- Addressing modes allowed:
- See syntax
- Function: As you all should know, the 68000 has in fact two A7
- registers. One A7 register is used when in supervisor-
- mode, the other when in usermode (this is: not in
- supervisor-mode. It is sometimes desirable for a
- program which is executing in supervisor mode to know
- the value of the usermode A7-register. This instruction
- provides a way to obtain and change the value of A7
- usermode-register.
- Example:
- Instruction Before After
- MOVE USP,A6 A7user=$12345678 A7user=$12345678
- A6 =$00000000 A6 =$12345678
- A7sup =$87654321 A7sup =$87654321
-
- Instruction: RESET
- Syntax: RESET (privileged instruction)
- Data sizes: none
- Condition codes affected:
- X
- N
- Z
- V
- C not affected
- Function: Reset all external devices. A device can be a chip like
- the 6850.
-
-
- Instruction: RTE (privileged instruction)
- Syntax: RTE
- Data sizes: none
- Condition codes affected:
- none
-
-
-
-
- Function: Every exception is terminated by this instruction. It
- can be compared to RTS. The only difference is that RTE
- will restore the SR in addition. Note that an
- exception-routine has the responsibility to save
- registers if this is important.
-
-
- Instruction: STOP (privileged instruction)
- Syntax: STOP #
- Data sizes: word
- Condition codes affected:
- All set as a direct result of the operand
- Addressing modes allowed:
- Source:
- #
- Function: Stop execution of a program until an exception occurs.
- The operand stored in the SR. Note that with the
- operand a minimum interrupt level can be determined.
- With this instruction it is possible to wait for a
- videochip interrupt to occur.
-
-
- Example:
- STOP #%0010011000011111
- Wait for an exception with a priority of 6 or 7 to
- occur and set the XNZVC-bits.
-
-
- Instruction: TRAP
- Syntax: TRAP #
- Data sizes: # must be >=0 and <=15
- Condition codes affected:
- X
- N
- Z
- V
- C not affected
-
-
-
-
-
-
-
- Function: This instruction generates an exception. The operand
- indicates an exception number. The vectors for the
- exceptions are located at addresses $80 to $BC. This
- instruction is mainly used to allow programs that
- execute in user-mode to call supervisor-mode routines.
- This way a user can be given a number of specific
- functions. In the ST trap vectors 2, 14 and 15 are used
- for GEM, BIOS and XBIOS functions. In the case of the
- ST the TRAP-instructions is preceded by instructions
- that put function numbers and parameters for these
- functions on the stack. This way it is possible to
- assign groups of functions to one trap-vector.
- Note that when calling a TRAP in user-mode the
- stackpointers change (supervisor-mode and user-mode,
- remember??). Thus, the MOVE USP instruction can be used
- to retrieve parameters that had been put on the stack.
-
-
- Instruction: TRAPV
- Syntax: TRAPV
- Data sizes: none
-
- Condition codes affected:
- none
- Function: When the V-bit is set an exception occurs. The
- exception vector is located at address $1C. When the V-
- bit is clear nothing happens. This instruction can be
- used by high-level languages to inform the user that an
- overflow error has occured.
-
-
-
- MC 68000 ASSEMBLY LANGUAGE COURSE PART X by Mark van den Boer
-
- Now all instructions of the 68000 have been explained it's time
- to bring this knowledge into practice. This last part of the
- course will deal with the subject of translating high-level
- constructs to the equivalent assembler constructs. The C program-
- ming language will be used as the high-level language which has
- to be translated to assembler. A note to those of you who are
- more familiar with Pascal or BASIC: litte imagination is needed
- to deduct the similar constructs in Pascal and BASIC.
- What now follows is a C-program which containing several commonly
- used data- and control structures. The examples show you how to
- translate these structures into assembler.
- There should also be a file called M68000.DOC on your ST NEWS
- disk. This file contains a quick-reference card containing all
- instructions and allowed addressing modes. This reference card
- has been made by Trustware, Inc. (an unregistered trademark of
- Victor Langeveld). I am very grateful to Victor for allowing me
- to include this card, since it's a rather tedious job to put
- together such a card. One thing's for sure: this card is one of
- the better of its kind and it's the most compact reference card
- for the 68000 I've ever seen.
- /*
- A function. (Called a procedure or function in Pascal
- and a subroutine in BASIC)
- Note how parameters are passed in the assembly language
- translation.
- Als pay attention to how local variables are stored.
- */
- int function (number, pointer)
- int number;
- char *pointer;
- {
- register int i, j;
- char *c;
-
- i = number - 1;
- c = pointer;
- c = "new Queensryche album: Operation Mindcrime";
- /* Note how a string is stored */
- return i; /* Note how a value is returned */
- }
-
-
- .text
- function:
- * offset of number = 8
- * offset of pointer = 10
- LINK A6,#-4
- * save registers
- MOVEM.L D6-D7,-(sp) * sp = A7
- * i in D7
- * j in D6
- * offset of c = -4
- * i = number - 1
- MOVE.W 8(A6),D7
- SUB.W #1,D7
- * c = pointer
- MOVE.L 10(A6),-4(A6)
- * c = "new Queensryche album: Operation Mindcrime"
- .data
-
-
-
-
-
- L2:
- .dc.b 'new Queensryche album: Operation Mindcrime',0
- MOVE.L #L2,-4(A6)
- * D0 is used for resulting values from functions
- * return i; D0 is always used for the result of a function
- MOVE.W D7,D0
- * restore registers
- MOVEM.L (sp)+,D6-D7
- UNLK A6
- * }
- RTS
-
- * global variables
- .bss
- * int i;
- i: .ds.w 1
- * char character
- character: .ds.b 1
- * int *i_pointer
- i_pointer: .ds.l 1
-
-
- * int i_array[10][5]
- i_array: .ds.w 10*5
- * one struct is in fact 3 bytes long, but for every structure
- * 4 bytes are reserved. This is because the 68000 can only
- * address words at even addresses.
- * struct { /* this is the equivalent of a record in PASCAL */
- * int i;
- * char c;
- * } structure[5];
- structure: .ds.b 4*5
-
-
- main()
- {
- /* assignment of a constant to a variable */
- i = 9;
-
- /* assignment of a constant to a variable */
- character = 'c';
-
- /* assignment of a constant to a variable */
- i_pointer = &i;
- /* watch how indexing of array is done */
- /* integer is 2 bytes, so the address of
- array-element [3][4] is:
- (3 * 5 (the length of i_array[3]) + 4)
- * 2 (size of an integer) = 38.
- So the integer should be stored at i_array + 38.
- */
- i_array[3][4] = *i_pointer;
-
- /* Now the distance in bytes from the beginning of the
- array must be computed during program execution,
- in contrary to the previous example.
- */
- i_array[i][i - 1] = 2;
-
- /* Assignments to arrays of structures */
- structure[1].i = 3;
- structure[i].c = character;
-
- /* expression evaluation and assignment */
- i = i_array[0][0] * i_array[0][1] +
- i_array[0][2] / i_array[0][3];
- /* conditional statement */
- if (i < i_array[i][i]) i = 1;
- else i = 2;
-
- /* while loop */
- while (i <= 10) i++;
- /* continue and break statements */
- while (i++ <= 10) {
- if (i != 4) continue;
- else break;
- }
-
- /* for loop */
- for (i = 4; i >= 0; i--) i_array[i][i] = i;
-
- /* do loop */
- do i++; while (i < 10 && i != 5);
-
- /* switch statement; watch the application of a
- jump-table. Pay special attention to how 'case 4'
- which must 'default' is solved.
-
- */
- switch (i) {
- case 0:
- i = 0;
- break;
- case 1:
- i = 5;
- break;
- case 2:
- case 3:
- i = 7;
- break;
- case 5:
- i = 1;
- break;
- default:
- i = 2;
- break;
- }
-
-
-
- /* switch statement;
- watch how 'case 999' has destroyed the
- jumptable-optimization.
- */
- switch (i) {
- case 0:
- i = 0;
- break;
- case 1:
- i = 5;
- break;
- case 2:
- case 3:
- i = 7;
- break;
- case 5:
- i = 1;
- break;
- case 999:
- /* This case should be tested seperately so
- the assembler code can be more efficient.
-
- */
- i = 100;
- break;
- default:
- i = 2;
- break;
- }
-
- /* manipulating bits */
- i = i & 0x2345;
- i = i | 0x2345;
- i = i ^ 0x2345;
- i = ~i;
- i <<= i;
-
- /* using the result of a function */
- i = function(5, &character);
-
- }
-
- .text
-
- main:
- * Reserve 4 bytes. This way, when the first parameter for a
- * function is pushed onto the stack, no pre-decrementing of sp
- * has to be done. This 'trick' is used by the DRI-C-compiler.
- LINK A6,#-4
- * i = 9
- MOVE.W #9,i
- * character = 'c'
- MOVE.B #'c,character
- * i_pointer = &i
- MOVE.L #i,i_pointer
- * i_array[3][4] = *i_pointer
- MOVE.L i_pointer,A0
- MOVE.W (A0),38+i_array
- * i_array[i][i - 1] = 2
- MOVE.W i,D0 * compute byte offset from first element
- MULS #10,D0
- MOVE.W i,D1
- SUB.W #1,D1
- ASL.W #1,D1 * multiply by 2 because an int is 2 bytes
- EXT.L D1
- ADD.L D1,D0
- ADD.L #i_array,D0
- MOVE.L D0,A0 * move computed address to address-reg
- MOVE.W #2,(A0)
- * structure[1].i = 3
- MOVE.W #3,4+structure
- * structure[i].c = character
- MOVE.W i,A0
- ADD.L A0,A0
- ADD.L A0,A0
- * Two ADD operations are faster than a MUL and a MOVE
- ADD.L #structure,A0
- MOVE.B character,2(A0)
- * i = i_array[0][0] * i_array[0][1] +
- * i_array[0][2] / i_array[0][3];
- MOVE.W i_array,D0
- MULS 2+i_array,D0
- MOVE.W 4+i_array,D1
- EXT.L D1
- DIVS 6+i_array,D1
- ADD.W D1,D0
- MOVE.W D0,i
- * if (i < i_array[i][i]) i = 1;
- * else i = 2;
- MOVE.W i,D0
- MULS #10,D0
- MOVE.W i,D1
- ASL.W #1,D1
- EXT.L D1
- ADD.L D1,D0
- MOVE.L D0,A0
- MOVE.L #i_array,A1
- MOVE.W 0(A0,A1.L),D0
- CMP i,D0
- BLE L4
- * i = 1
- MOVE.W #1,i
- BRA L5
- L4:
- * i = 2
- MOVE.W #2,i
- L5:
- BRA L8
-
-
- * while (i <= 10) i++;
- * This loop has been optimized:
- * one BRA instruction was saved by putting the test after the
- * do-part. The label L5: BRA L8 takes care that the while
- * condition is executed first at the beginning of the loop
- L7:
- ADD.W #1,i
- L8:
- CMP.W #10,i
- BLE L7
- * while (i++ <= 10) {
- * if (i != 4) continue;
- * else break;
- * }
- L6:
- BRA L11
- L10:
- CMP.W #4,i
- BNE L11
- BRA L9
-
-
- L11:
- CMP #10,i
- MOVE.W SR,D0 * save condition codes
- ADD.W #1,i
- MOVE D0,CCR * and restore
- BLE L10
- * for (i = 4; i >= 0; i--) i_array[i][i] = i
- L9:
- MOVE.W #4,i
- BRA L14
- L15:
- MOVE.W i,D0
- MULS #10,D0
- MOVE.W i,D1
- ASL.W #1,D1
- EXT.L D1
- ADD.L D1,D0
- ADD.L #i_array,D0
- MOVE.L D0,A0
- MOVE.W i,(A0)
- L13:
- SUB.W #1,i
- L14:
- TST i
- BGE L15
- L12:
- * do i++; while (i < 10 && i != 5);
- L18:
- ADD.W #1,i
- L17:
- CMP.W #10,i
- BGE L10000
- CMP.W #5,i
- BNE L18
- L10000:
- * switch (i) {
- * case 0:
- * i = 0;
- * break;
- * case 1:
- * i = 5;
- * break;
-
-
- * case 2:
- * case 3:
- * i = 7;
- * break;
- * case 5:
- * i = 1;
- * break;
- * default:
- * i = 2;
- * break;
- * }
- L16:
- MOVE.W i,D0
- BRA L20
- L21:
- CLR.W i
- BRA L19
- L22:
- MOVE.W #5,i
- BRA L19
-
-
- L23:
- L24:
- MOVE.W #7,i
- BRA L19
- L25:
- MOVE.W #1,i
- BRA L19
- L26:
- MOVE.W #2,i
- BRA L19
- L20:
- * Test if i is in case-range
- * if not goto default
- * if in range compute address to jump to
- CMP.W #5,D0
- BHI L26
- ASL.W #2,D0
- MOVE.W D0,A0
- ADD.L #L27,A0
- MOVE.L (A0),A0
- JMP (A0)
- .data
- L27:
- * jumptable
- .dc.l L21
- .dc.l L22
- .dc.l L23
- .dc.l L24
- .dc.l L26
- .dc.l L25
- .text
- L19:
- * switch (i) {
- * case 0:
- * i = 0;
- * break;
- * case 1:
- * i = 5;
- * break;
- * case 2:
- * case 3:
- * i = 7;
- * break;
-
- * case 5:
- * i = 1;
- * break;
- * case 999:
- * /* This case should be tested seperately so
- * the assembler code can be more efficient.
- * */
- * i = 100;
- * break;
- * default:
- * i = 2;
- * break;
- * }
- MOVE.W i,D0
- BRA L29
- L30:
- CLR.W i
- BRA L28
- L31:
- MOVE.W #5,i
- BRA L28
-
- L32:
- L33:
- MOVE.W #7,i
- BRA L28
- L34:
- MOVE.W #1,i
- BRA L28
- L35:
- MOVE.W #100,i
- BRA L28
- L36:
- MOVE.W #2,i
- BRA L28
- BRA L28
- L29:
- EXT.L D0
- MOVE.L #L37,A0
- MOVE.W #6,D1
-
-
-
-
- L38:
- CMP.L (A0)+,D0
- DBEQ D1,L38
- MOVE.L 24(A0),A0
- JMP (A0)
- .data
- L37:
- * table of case values
- .dc.l 0
- .dc.l 1
- .dc.l 2
- .dc.l 3
- .dc.l 5
- .dc.l 999
- .dc.l 0
- * jump table
- .dc.l L30
- .dc.l L31
- .dc.l L32
- .dc.l L33
- .dc.l L34
- .dc.l L35
- .dc.l L36
- .text
- L28:
- * i = i & 0x2345
- ANDI.W #$2345,i
- * i = i | 0x2345
- ORI.W #$2345,i
- * i = i ^ 0x2345
- EORI.W #$2345,i
- * i = ~i
- NOT.W i
- * i <<= i
- MOVE.W i,D1
- MOVE.W D1,D0
- ASL.W D1,D0
- MOVE.W D0,i
- * i = function (5, &character)
- MOVE.W #51,(sp)
- MOVE.L #character,-(sp)
- ADDQ.L #4,sp
- MOVE.W D0,i
-
- L3:
- UNLK A6
- RTS
-
-
- Hope you had much fun with this course and that you learnt a lot!